#!/usr/bin/python2
import os
import sys
import errno
import uuid
import subprocess
import time

sys.path.insert(0, os.path.abspath(os.path.split(os.path.realpath(__file__))[0]) + "/../lich/admin/")

from utils import _print1, _print2, _get_value, Exp, _exec_pipe, _derror, _dmsg, _dwarn
from storage import Storage
from config import Config
from testobject import TestObject

class TestSnapshot():
    def __init__(self, src):
        self.src = src
        self.config = Config()
        self.storage = Storage(self.config)

    def __snapshot_try_remove(self, path):
        retry = 0
        while (1):
            try:
                lst = self.storage.remove(path)
            except Exp, e:
                if (e.errno == errno.ENOENT):
                    break
                elif (e.errno == errno.EAGAIN and retry < 40):
                    time.sleep(1)
                    retry += 1
                    continue
                else:
                    raise

    def __snapshot_remove(self, snap):
        retry = 0
        while (1):
            try:
                lst = self.storage.list(snap)
            except Exp, e:
                if (e.errno == errno.ENOENT):
                    break
                elif (e.errno == errno.EAGAIN and retry < 40):
                    time.sleep(1)
                    retry += 1
                    continue
                else:
                    raise

            for i in lst:
                self.__snapshot_try_remove(snap + '/' + i)

            self.__snapshot_try_remove(snap)

    def snapshot(self, dist):
        print ("create snapshot %s of %s" % (dist, self.src))

        retry = 0
        while (1):
            try:
                self.storage.snapshot(self.src, dist);
            except Exp, e:
                if (retry > 40):
                    raise

                elif (e.errno == errno.EAGAIN):
                    _derror("snapshot error")
                    self.__snapshot_remove(dist)
                    time.sleep(1)
                    retry += 1
                    continue
                else:
                    raise

            break

def testsnapshot(count):
    tab = {}
    for i in range(count):
        tab[str(uuid.uuid1())] = str(uuid.uuid1())

    src = '/src/' + str(uuid.uuid1())

    print ("create volume group %s" % (src))
    srcbucket = TestObject(src)
    srcbucket.create(tab)

    print ("create volume group %s" % (src))

    srcbucket.check()

    dist = '/dist/' + str(uuid.uuid1())

    print ("create snapshot %s of volume group %s" % (dist, src))

    snapshot = TestSnapshot(src)
    snapshot.snapshot(dist)

    distbucket = TestObject(dist, tab)

    print ("check snapshot %s of volume group %s" % (dist, src))

    distbucket.check()

    for (k, v) in tab.items():
        tab[k] = str(uuid.uuid1()) + str(uuid.uuid1())

    print ("update volume group %s" % (src))

    srcbucket.update(tab)

    print ("check volume group %s" % (src))

    srcbucket.check()

    print ("check snapshot %s of volume group %s" % (dist, src))    

    distbucket.check()

    for (k, v) in tab.items():
        tab[k] = str(uuid.uuid1()) + str(uuid.uuid1())

    print ("update snapshot %s of volume group %s" % (dist, src))    

    distbucket.update(tab)

    print ("check volume group %s" % (src))    

    distbucket.check()

if __name__ == '__main__':
    testsnapshot(3)
